package main

import (
	"crypto/rand"
	"crypto/rsa"
	"crypto/sha256"
	"crypto/x509"
	"encoding/pem"
	"fmt"
	"io"
	"io/ioutil"
	"log"
	"os"
)

const filepath = "D:\\code\\go\\gorasome\\testa.bin"
const keyPath = "D:\\code\\go\\gorasome\\server\\key_20241224_090342.txt"

func main() {
	// 读取加密数据
	encryptedData, err := readEncryptedFile(filepath)
	if err != nil {
		fmt.Println("读取加密文件时出错:", err)
		return
	}

	// 读取私钥
	privateKey, err := readPrivateKey(keyPath)
	if err != nil {
		fmt.Println("读取私钥时出错:", err)
		return
	}

	// 解密数据
	decryptedData, err := decryptRSA(privateKey, encryptedData)
	if err != nil {
		fmt.Println("解密数据时出错:", err)
		return
	}

	// 输出解密后的数据
	fmt.Println("解密后的数据:", string(decryptedData))
	fmt.Println("解密后的数据长度:", len(decryptedData))

	if repaireFile(filepath, decryptedData) != nil {
		fmt.Println("写入文件时出错")
	} else {
		fmt.Println("写入文件成功")
	}
}

// 将解密后的数据写回原始文件
func repaireFile(filePath string, data []byte) error {
	// 打开文件以进行读写
	file, err := os.OpenFile(filePath, os.O_RDWR|os.O_TRUNC, 0644)
	if err != nil {
		log.Fatalf("无法打开文件: %v", err)
		return err
	}
	defer file.Close()

	// 将文件指针移动到开头
	if _, err := file.Seek(0, 0); err != nil {
		log.Fatalf("移动文件指针时出错: %v", err)
		return err
	}

	// 写入解密后的数据
	if _, err := file.Write(data); err != nil {
		log.Fatalf("写入文件时出错: %v", err)
		return err
	}

	return nil
}

// 读取加密文件的前256个字节
func readEncryptedFile(filePath string) ([]byte, error) {
	file, err := os.Open(filePath)
	if err != nil {
		return nil, err
	}
	defer file.Close()

	buffer := make([]byte, 256)
	n, err := io.ReadFull(file, buffer)
	if err != nil {
		return nil, err
	}

	return buffer[:n], nil
}

// 读取 PEM 格式的私钥
func readPrivateKey(filePath string) (*rsa.PrivateKey, error) {
	keyData, err := ioutil.ReadFile(filePath)
	if err != nil {
		return nil, err
	}

	block, _ := pem.Decode(keyData)
	if block == nil || block.Type != "PRIVATE KEY" {
		return nil, fmt.Errorf("无效的私钥格式")
	}

	privateKey, err := x509.ParsePKCS1PrivateKey(block.Bytes)
	if err != nil {
		return nil, err
	}

	return privateKey, nil
}

// 使用私钥解密数据
func decryptRSA(privateKey *rsa.PrivateKey, encryptedData []byte) ([]byte, error) {
	// 使用 SHA-256 作为哈希函数
	hash := sha256.New()
	decryptedData, err := rsa.DecryptOAEP(hash, rand.Reader, privateKey, encryptedData, nil)
	if err != nil {
		return nil, err
	}
	return decryptedData, nil
}
